#pragma once

#include "os/types.h"

typedef struct {
	u8 *buff;
	u16 size;
	u16 head;
	u16 tail;
} byte_queue_t;

u8 *byte_queue_head(byte_queue_t *queue);
bool byte_queue_empty(const byte_queue_t *queue);
bool byte_queue_readable(const byte_queue_t *queue);
bool byte_queue_full(const byte_queue_t *queue);
bool byte_queue_writeable(const byte_queue_t *queue);
u16 byte_queue_get_used(const byte_queue_t *queue);
u16 byte_queue_get_free(const byte_queue_t *queue);

void byte_queue_reset(byte_queue_t *queue);
void byte_queue_init(byte_queue_t *queue, u8 *buff, u16 size);
u16 byte_queue_write(byte_queue_t *queue, const u8 *buff, u16 size);
u16 byte_queue_write_byte(byte_queue_t *queue, u8 byte);
u16 byte_queue_read(byte_queue_t *queue, u8 *buff, u16 size);
void byte_queue_fill(byte_queue_t *queue, u8 *buff, u16 size);
void byte_queue_skip(byte_queue_t *queue, u16 length);
u16 byte_queue_peek(byte_queue_t *queue);

void byte_queue_alloc_init(byte_queue_t *queue, u8 *buff, u8 size);
void byte_queue_alloc_reset(byte_queue_t *queue);
u8 byte_queue_alloc(byte_queue_t *queue);
void byte_queue_free(byte_queue_t *queue, u8 index);
